import 'dart:async';
import 'dart:developer' as developer;
import 'package:get/get.dart';
import 'package:jpush_flutter/jpush_flutter.dart';
import '../utils/smart_notification_util.dart';

/// 极光推送服务
/// 
/// 🎯 核心职责：
/// - 极光推送SDK初始化和配置
/// - 处理后台推送通知
/// - 处理通知点击事件
/// - 管理推送别名和标签
/// - 配合融云IM实现完整的消息推送方案
/// 
/// 📱 推送策略：
/// - App在前台：使用SmartNotificationUtil显示应用内通知
/// - App在后台：使用极光推送显示系统通知
/// - 点击通知：跳转到对应聊天页面
/// 
/// 💡 使用场景：
/// - 用户收到好友消息时推送通知
/// - 用户收到好友申请时推送通知
/// - 用户收到活动申请时推送通知
class JPushService extends GetxService {
  static JPushService get to => Get.find<JPushService>();
  
  // ==================== 极光推送配置 ====================
  
  /// 极光推送 AppKey
  /// 获取地址：https://www.jiguang.cn/
  static const String appKey = '7068728651334ce710692ad9'; // 极光推送AppKey
  
  /// 推送渠道标识
  static const String channel = 'developer-default';
  
  // ==================== JPush实例 ====================
  
  final JPush _jpush = JPush();
  
  // ==================== 响应式状态 ====================
  
  /// 设备注册ID（用于服务端精确推送）
  final RxString registrationId = ''.obs;
  
  /// 是否已初始化
  final RxBool isInitialized = false.obs;
  
  /// 推送是否已停止
  final RxBool isPushStopped = false.obs;
  
  // ==================== 初始化 ====================
  
  @override
  Future<void> onInit() async {
    super.onInit();
    developer.log('🔔 =============== 极光推送服务初始化 ===============');
    
    try {
      // 🔥 重要：先设置事件监听器，再调用setup
      _setupEventHandlers();
      
      // 初始化极光推送SDK
      await _initializeJPush();
      
      developer.log('✅ 极光推送服务初始化完成');
      
    } catch (e) {
      developer.log('💥 极光推送服务初始化失败: $e');
      rethrow;
    }
  }
  
  /// 初始化极光推送SDK
  Future<void> _initializeJPush() async {
    try {
      developer.log('🔧 开始初始化极光推送SDK...');
      
      // 调用setup方法初始化（setup返回void，不需要await）
      _jpush.setup(
        appKey: appKey,
        channel: channel,
        production: false, // false=开发环境，true=生产环境
        debug: true,       // 开启调试日志
      );
      
      isInitialized.value = true;
      developer.log('✅ 极光推送SDK初始化成功');
      
      // 获取设备注册ID
      await _getRegistrationId();
      
      // iOS：申请推送权限
      await _applyPushAuthorityForIOS();
      
    } catch (e) {
      developer.log('💥 极光推送SDK初始化失败: $e');
      rethrow;
    }
  }
  
  /// 设置事件监听器
  void _setupEventHandlers() {
    developer.log('🔧 设置极光推送事件监听器...');
    
    _jpush.addEventHandler(
      // 🔥 接收通知回调（App在前台时触发）
      onReceiveNotification: (Map<String, dynamic> message) async {
        developer.log('📨 ========== 收到极光通知 ==========');
        developer.log('   消息内容: $message');
        developer.log('   App状态: 前台');
        
        try {
          // 🔥 App在前台时，使用SmartNotificationUtil显示应用内通知
          // 从消息中提取必要信息
          final extras = message['extras'] as Map<String, dynamic>? ?? {};
          final alert = message['alert'] as String? ?? '';
          
          // 提取发送者信息
          final senderUserId = extras['senderUserId'] as String?;
          final senderName = extras['senderName'] as String? ?? '未知用户';
          final senderAvatar = extras['senderAvatar'] as String? ?? '';
          final friendId = extras['friendId'] as int?;
          final messageContent = extras['messageContent'] as String? ?? alert;
          
          if (senderUserId != null) {
            developer.log('🔔 显示应用内通知');
            await SmartNotificationUtil.instance.handleMessageNotification(
              senderUserId: senderUserId,
              friendId: friendId,
              senderName: senderName,
              senderAvatar: senderAvatar,
              messageContent: messageContent,
            );
          } else {
            developer.log('⚠️ 消息缺少发送者信息，无法显示通知');
          }
          
        } catch (e) {
          developer.log('💥 处理极光通知异常: $e');
        }
      },
      
      // 🔥 点击通知回调（用户点击通知栏消息时触发）
      onOpenNotification: (Map<String, dynamic> message) async {
        developer.log('👆 ========== 用户点击了极光通知 ==========');
        developer.log('   消息内容: $message');
        
        try {
          // 从消息中提取跳转信息
          final extras = message['extras'] as Map<String, dynamic>? ?? {};
          
          final friendId = extras['friendId'] as int?;
          final friendPhone = extras['senderUserId'] as String?;
          final friendName = extras['senderName'] as String? ?? '未知用户';
          final friendAvatar = extras['senderAvatar'] as String? ?? '';
          
          if (friendPhone != null && friendPhone.isNotEmpty) {
            developer.log('🚀 跳转到聊天页面');
            developer.log('   好友ID: $friendId');
            developer.log('   好友手机: $friendPhone');
            developer.log('   好友名称: $friendName');
            
            // 跳转到聊天页面
            Get.toNamed(
              '/message_message_chat',
              arguments: {
                'friendId': friendId,
                'friendPhone': friendPhone,
                'friendName': friendName,
                'friendAvatar': friendAvatar,
              },
            );
            
            developer.log('✅ 路由跳转成功');
          } else {
            developer.log('⚠️ 消息缺少跳转信息');
          }
          
        } catch (e) {
          developer.log('💥 处理通知点击异常: $e');
        }
      },
      
      // 🔥 接收自定义消息回调
      onReceiveMessage: (Map<String, dynamic> message) async {
        developer.log('📬 ========== 收到极光自定义消息 ==========');
        developer.log('   消息内容: $message');
        
        // 自定义消息可以用于应用内的特殊逻辑，不会显示在通知栏
        // 可以根据需要在这里处理自定义消息
      },
    );
    
    developer.log('✅ 极光推送事件监听器设置完成');
  }
  
  /// 获取设备注册ID
  Future<void> _getRegistrationId() async {
    try {
      developer.log('🔍 获取设备注册ID...');
      
      final rid = await _jpush.getRegistrationID();
      
      if (rid.isNotEmpty) {
        registrationId.value = rid;
        developer.log('✅ 设备注册ID: $rid');
        developer.log('💡 提示：服务端可以使用此ID进行精确推送');
      } else {
        developer.log('⚠️ 设备注册ID为空');
      }
      
    } catch (e) {
      developer.log('💥 获取设备注册ID失败: $e');
    }
  }
  
  /// iOS：申请推送权限
  Future<void> _applyPushAuthorityForIOS() async {
    try {
      // iOS平台需要申请推送权限
      if (GetPlatform.isIOS) {
        developer.log('🍎 iOS平台：申请推送权限...');
        
        // applyPushAuthority返回void，不需要await
        _jpush.applyPushAuthority(
          NotificationSettingsIOS(
            sound: true,  // 允许声音
            alert: true,  // 允许通知
            badge: true,  // 允许角标
          ),
        );
        
        developer.log('✅ iOS推送权限申请完成');
      }
      
    } catch (e) {
      developer.log('💥 iOS推送权限申请失败: $e');
    }
  }
  
  // ==================== 别名管理 ====================
  
  /// 设置推送别名
  /// 
  /// 一般用于绑定用户ID，方便服务端按用户ID推送
  /// [alias] 用户唯一标识（如用户ID或手机号）
  Future<bool> setAlias(String alias) async {
    try {
      if (alias.isEmpty) {
        developer.log('⚠️ 别名不能为空');
        return false;
      }
      
      developer.log('🔧 设置推送别名: $alias');
      
      final result = await _jpush.setAlias(alias);
      final code = result['code'] as int?;
      
      if (code == 0) {
        developer.log('✅ 别名设置成功');
        return true;
      } else {
        developer.log('❌ 别名设置失败: code=$code');
        return false;
      }
      
    } catch (e) {
      developer.log('💥 设置别名异常: $e');
      return false;
    }
  }
  
  /// 删除推送别名
  Future<bool> deleteAlias() async {
    try {
      developer.log('🗑️ 删除推送别名...');
      
      final result = await _jpush.deleteAlias();
      final code = result['code'] as int?;
      
      if (code == 0) {
        developer.log('✅ 别名删除成功');
        return true;
      } else {
        developer.log('❌ 别名删除失败: code=$code');
        return false;
      }
      
    } catch (e) {
      developer.log('💥 删除别名异常: $e');
      return false;
    }
  }
  
  // ==================== 标签管理 ====================
  
  /// 添加标签
  /// 
  /// 标签用于给用户分组，方便按组推送
  /// [tags] 标签列表
  Future<bool> addTags(List<String> tags) async {
    try {
      if (tags.isEmpty) {
        developer.log('⚠️ 标签列表不能为空');
        return false;
      }
      
      developer.log('🏷️ 添加标签: $tags');
      
      final result = await _jpush.addTags(tags);
      final code = result['code'] as int?;
      
      if (code == 0) {
        developer.log('✅ 标签添加成功');
        return true;
      } else {
        developer.log('❌ 标签添加失败: code=$code');
        return false;
      }
      
    } catch (e) {
      developer.log('💥 添加标签异常: $e');
      return false;
    }
  }
  
  /// 删除标签
  Future<bool> deleteTags(List<String> tags) async {
    try {
      if (tags.isEmpty) {
        developer.log('⚠️ 标签列表不能为空');
        return false;
      }
      
      developer.log('🗑️ 删除标签: $tags');
      
      final result = await _jpush.deleteTags(tags);
      final code = result['code'] as int?;
      
      if (code == 0) {
        developer.log('✅ 标签删除成功');
        return true;
      } else {
        developer.log('❌ 标签删除失败: code=$code');
        return false;
      }
      
    } catch (e) {
      developer.log('💥 删除标签异常: $e');
      return false;
    }
  }
  
  /// 设置标签（覆盖原有标签）
  Future<bool> setTags(List<String> tags) async {
    try {
      developer.log('🏷️ 设置标签: $tags');
      
      final result = await _jpush.setTags(tags);
      final code = result['code'] as int?;
      
      if (code == 0) {
        developer.log('✅ 标签设置成功');
        return true;
      } else {
        developer.log('❌ 标签设置失败: code=$code');
        return false;
      }
      
    } catch (e) {
      developer.log('💥 设置标签异常: $e');
      return false;
    }
  }
  
  /// 清空所有标签
  Future<bool> cleanTags() async {
    try {
      developer.log('🧹 清空所有标签...');
      
      final result = await _jpush.cleanTags();
      final code = result['code'] as int?;
      
      if (code == 0) {
        developer.log('✅ 标签清空成功');
        return true;
      } else {
        developer.log('❌ 标签清空失败: code=$code');
        return false;
      }
      
    } catch (e) {
      developer.log('💥 清空标签异常: $e');
      return false;
    }
  }
  
  /// 获取所有标签
  Future<List<String>> getAllTags() async {
    try {
      developer.log('🔍 获取所有标签...');
      
      final result = await _jpush.getAllTags();
      final tags = result['tags'] as List?;
      
      if (tags != null) {
        final tagList = tags.map((e) => e.toString()).toList();
        developer.log('✅ 当前标签: $tagList');
        return tagList;
      } else {
        developer.log('⚠️ 标签列表为空');
        return [];
      }
      
    } catch (e) {
      developer.log('💥 获取标签异常: $e');
      return [];
    }
  }
  
  // ==================== 推送控制 ====================
  
  /// 停止推送服务
  /// 
  /// 调用后将不再接收推送通知
  Future<bool> stopPush() async {
    try {
      developer.log('🛑 停止推送服务...');
      
      await _jpush.stopPush();
      isPushStopped.value = true;
      
      developer.log('✅ 推送服务已停止');
      return true;
      
    } catch (e) {
      developer.log('💥 停止推送服务异常: $e');
      return false;
    }
  }
  
  /// 恢复推送服务
  /// 
  /// 恢复接收推送通知
  Future<bool> resumePush() async {
    try {
      developer.log('▶️ 恢复推送服务...');
      
      await _jpush.resumePush();
      isPushStopped.value = false;
      
      developer.log('✅ 推送服务已恢复');
      return true;
      
    } catch (e) {
      developer.log('💥 恢复推送服务异常: $e');
      return false;
    }
  }
  
  // ==================== 本地通知 ====================
  
  /// 发送本地通知
  /// 
  /// 用于定时提醒等场景
  Future<bool> sendLocalNotification({
    required int id,
    required String title,
    required String content,
    required DateTime fireTime,
    String? subtitle,
    int? badge,
  }) async {
    try {
      developer.log('📬 发送本地通知...');
      developer.log('   标题: $title');
      developer.log('   内容: $content');
      developer.log('   触发时间: $fireTime');
      
      final localNotification = LocalNotification(
        id: id,
        title: title,
        buildId: 1,
        content: content,
        fireTime: fireTime,
        subtitle: subtitle,
        badge: badge,
      );
      
      final result = await _jpush.sendLocalNotification(localNotification);
      developer.log('✅ 本地通知已设置: $result');
      
      return true;
      
    } catch (e) {
      developer.log('💥 发送本地通知异常: $e');
      return false;
    }
  }
  
  /// 清除所有通知
  Future<void> clearAllNotifications() async {
    try {
      developer.log('🧹 清除所有通知...');
      await _jpush.clearAllNotifications();
      developer.log('✅ 所有通知已清除');
    } catch (e) {
      developer.log('💥 清除通知异常: $e');
    }
  }
  
  // ==================== iOS专用 ====================
  
  /// 设置应用角标数量（iOS）
  Future<bool> setBadge(int badge) async {
    try {
      if (!GetPlatform.isIOS) {
        developer.log('⚠️ 此功能仅iOS平台支持');
        return false;
      }
      
      developer.log('🔢 设置iOS角标: $badge');
      
      final result = await _jpush.setBadge(badge);
      final code = result['code'] as int?;
      
      if (code == 0) {
        developer.log('✅ 角标设置成功');
        return true;
      } else {
        developer.log('❌ 角标设置失败: code=$code');
        return false;
      }
      
    } catch (e) {
      developer.log('💥 设置角标异常: $e');
      return false;
    }
  }
  
  /// 获取启动App的通知（iOS）
  /// 
  /// 用于App冷启动时获取点击的通知内容
  Future<Map<String, dynamic>?> getLaunchAppNotification() async {
    try {
      if (!GetPlatform.isIOS) {
        developer.log('⚠️ 此功能仅iOS平台支持');
        return null;
      }
      
      developer.log('🔍 获取启动App的通知...');
      
      final result = await _jpush.getLaunchAppNotification();
      
      if (result.isNotEmpty) {
        developer.log('✅ 获取到启动通知: $result');
        return Map<String, dynamic>.from(result);
      } else {
        developer.log('⚠️ 无启动通知');
        return null;
      }
      
    } catch (e) {
      developer.log('💥 获取启动通知异常: $e');
      return null;
    }
  }
  
  // ==================== 清理 ====================
  
  @override
  void onClose() {
    developer.log('🧹 极光推送服务正在清理...');
    super.onClose();
  }
}

